package com.shloma.bbts.tcp.client;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.shloma.bbts.tcp.TcpUtils;

/**
 * 作为客户端请求企业服务
 * <p>
 *
 * @author xuefeng.shi
 * @date 2018/12/09
 * @version v1.0.0
 */
@Service
public class RequestCorpClient {
	private static final Logger logger = LoggerFactory.getLogger(RequestCorpClient.class);
	public static String CILENT_IP;
	private static int CLIENT_PORT;
	public volatile ThreadLocal<Boolean> threadLocal = new ThreadLocal<Boolean>() {
		protected Boolean initialValue() {
			return true;
		};
	};

	public byte[] submit(byte[] requestBytesData) {

		Selector selector = null;
		SocketChannel clientChannel = null;
		byte[] responseData = null;
		try {
			selector = Selector.open();
			clientChannel = SocketChannel.open();
			clientChannel.configureBlocking(false);
			clientChannel.connect(new InetSocketAddress(CILENT_IP, CLIENT_PORT));
			clientChannel.register(selector, SelectionKey.OP_CONNECT);
			while (threadLocal.get()) {
				selector.select(5000 * 1000l);
				Iterator<SelectionKey> it = selector.selectedKeys().iterator();
				while (it.hasNext()) {
					SelectionKey selectionKey = it.next();
					it.remove();
					if (selectionKey.isConnectable()) {
						logger.info("连接企业通讯机开始 IP:{} PORT:{}", CILENT_IP, CLIENT_PORT);
						SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
						if (socketChannel.isConnectionPending()) {
							socketChannel.finishConnect();
						}
						socketChannel.configureBlocking(false);
						socketChannel.register(selector, SelectionKey.OP_WRITE);
					} else if (selectionKey.isReadable()) {
						threadLocal.set(false);

						SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
						responseData = TcpUtils.readDataFromChannel(socketChannel);

						logger.info("接收企业返回数据：responseData:{}", new String(responseData));
					} else if (selectionKey.isWritable()) {
						ByteBuffer sendBuffer = ByteBuffer.wrap(requestBytesData);
						SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
						socketChannel.write(sendBuffer);
						socketChannel.register(selector, SelectionKey.OP_READ);
						logger.info("发送企业请求数据：requestData:{}", new String(requestBytesData));
					}
				}
			}
		} catch (IOException e) {
			logger.error("连接企业通讯机失败", e);
		} finally {
			if (clientChannel != null) {
				try {
					clientChannel.close();
				} catch (IOException e) {
					logger.error("clientChannel close error!!!", e);
				}
			}
			if (selector != null) {
				try {
					selector.close();
				} catch (IOException e) {
					logger.error("selector close error!!!", e);
				}
			}
		}
		threadLocal.remove();
		return responseData;
	}

	public void initClient(String cilentIp, int clientPort) {
		logger.info(">>>>>> 初始化请求企业服务客户端：IP:{} PORT:{}", cilentIp, clientPort);
		CILENT_IP = cilentIp;
		CLIENT_PORT = clientPort;
	}
}